﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;


namespace Gaea.CodeFirst.Oracle
{
    public class OracleOperateTable : ITable
    {
        public async Task CreateTable<T>(OperateTableContext operateTableContext) where T : class
        {
            await CreateTable(operateTableContext);
        }

        public async Task AlterTable<T>(OperateTableContext operateTableContext) where T : class
        {
            await AlterTable(operateTableContext);
        }

        public async Task CreateTable(OperateTableContext operateTableContext)
        {
            PropertyInfo[] propertyInfo = operateTableContext.typeOfGaeaSon.GetProperties();
            string ColumnSql = "";
            var sql = "";
            foreach (var property in propertyInfo)
            {
                var column_name = property.Name;
                var column_type = property.PropertyType.Name;

                var attributes = property.GetCustomAttributes();
                //var attributes = property.GetCustomAttributes<GaeaSonStringLengthAttribute>();

                if (column_type == "String")
                {
                    foreach (var attribute in attributes)
                    {
                        var stringLength = (int)attribute.GetType().GetProperty("StringLength").GetValue(attribute);
                        column_type = "varchar(" + stringLength + ")";
                    }

                }
                else if (column_type == "Int32")
                {
                    column_type = "int";
                }
                ColumnSql += column_name + " " + column_type + ",";
            }
            ColumnSql = ColumnSql.TrimEnd(',');
            var tableName = operateTableContext.TableName.TrimEnd('`');
            tableName = tableName.TrimStart('`');
            //var sequence = "create sequence SEQ_T_RECV minvalue 1 maxvalue 9999999 start with 1 increment by 1 cache 50;";
            //gaeaBasicPower.Execute(sequence, null);
            sql = "CREATE TABLE " + tableName + " ( " + ColumnSql + " );";
            await operateTableContext.gaeaBasicPower.ExecuteAsync(sql, null);
            //var trigger = "CREATE OR REPLACE TRIGGER \"" + gaeaBasicPower.CallGaeaName(gaeaBasicPower, typeOfGaea) + "_trig\" BEFORE INSERT ON " + gaeaBasicPower.CallGaeaName(gaeaBasicPower, typeOfGaea) + " REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW DECLARE BEGIN  SELECT SEQ_T_RECV.NEXTVAL INTO :NEW.ID FROM DUAL; END " + gaeaBasicPower.CallGaeaName(gaeaBasicPower, typeOfGaea) + "_trig;";
            //await gaeaBasicPower.ExecuteAsync(trigger, null);

        }

        public async Task AlterTable(OperateTableContext operateTableContext)
        {
            PropertyInfo[] propertyInfo = operateTableContext.typeOfGaeaSon.GetProperties();
            string ColumnSql = "";
            Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();

            var allColumns = await operateTableContext.gaeaBasicPower.FindAsync<string>("SELECT * FROM ALL_COL_COMMENTS T WHERE  T.TABLE_NAME='' AND OWNER=''", new { });
            var enumerator = allColumns.GetEnumerator();
            while (enumerator.MoveNext())
            {
                string ColumnName = enumerator.Current;
                string ColumnType = enumerator.Current;
                keyValuePairs.Add(ColumnName, ColumnType);    //将数据库表所有字段名及类型存入字典
            }

            foreach (var property in propertyInfo)
            {
                var column_name = property.Name;
                var column_type = property.PropertyType.Name;

                if (column_type =="String")
                {
                    var attributes = property.GetCustomAttributes();
                    foreach (var attribute in attributes)
                    {
                        var stringLength = (int)attribute.GetType().GetProperty("StringLength").GetValue(attribute);
                        column_type = "varchar(" + stringLength + ")";
                    }

                }
                else if (column_type == "Int32")
                {
                    column_type = "int";
                }

                //与字典内数据对比，将没有的字段在数据表内新增
                if (keyValuePairs.ContainsKey(column_name) == false)
                {
                    ColumnSql = column_name + column_type;
                    var sql = "Alter TABLE " + operateTableContext.TableName + " Add " + ColumnSql + " ;";
                    await operateTableContext.gaeaBasicPower.ExecuteAsync(sql, null);
                }
                //包含该字段名，但类型不同的报错
                else if (keyValuePairs.ContainsKey(column_name) == true && keyValuePairs[column_name] != column_type)
                {
                    //throw new Exception("This field already exists,and type is different!");
                    Console.WriteLine(column_name + " is already exists,Db Type is " + keyValuePairs[column_name] + " ,and code Type is " + column_type);
                }
            }
        }
    }
}
